package com.googlecode.mcwalle.response;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * 
 * 对文本行类型的返回返回值的封装
 * 
 * @author Li Weibo (weibo.leo@gmail.com) //I believe spring-brother
 * @since 2011-10-28 下午05:33:53
 */
public class TextLineResponse implements Iterable<String>{
	
	private BufferedReader reader;
	
	public TextLineResponse(InputStream is) {
		reader = new BufferedReader(new InputStreamReader(is));
	}

	public String readOneLine() {
		try {
			return reader.readLine();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public Iterator<String> iterator() {
		return new IteratorImpl();
	}
	
	private class IteratorImpl implements Iterator<String> {

		private static final int STATE_INIT = 0;	//初始状态
		
		private static final int STATE_HASNEXT_INVOKED = 1;	//调用过hasNext()方法后的状态
		
		private static final int STATE_NEXT_INVOKED = 2;	//调用过next()方法后的状态
		
		private String justReadLine;
		
		private int state = STATE_INIT;	//state的作用是帮助判断调用时序，即必须以此调用hasNext()方法和next()方法
		
		IteratorImpl() {
			justReadLine = readOneLine();
		}
		
		@Override
		public boolean hasNext() {
			
			if (state != STATE_INIT && state != STATE_NEXT_INVOKED) {
				throw new IllegalStateException();
			}
			
			state = STATE_HASNEXT_INVOKED;	
			
			if (justReadLine == null) {
				return false;
			} else {
				if (justReadLine.equals("ERROR") || justReadLine.equals("END")) {
					return false;
				} else {
					return true;
				}
			}
		}

		@Override
		public String next() {
			
			if (state != STATE_HASNEXT_INVOKED) {
				throw new IllegalStateException();
			}
			
			if (justReadLine == null || justReadLine.equals("ERROR") || justReadLine.equals("END")) {
				throw new NoSuchElementException();
			}
			String tmp = justReadLine;
			justReadLine = readOneLine();
			
			state = STATE_NEXT_INVOKED;
			
			return tmp;
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}
	}
}
